package com.chuangjiangx.member.stored.ddd.application;


import com.chuangjiangx.domain.shared.model.PayEntry;
import com.chuangjiangx.member.stored.ddd.application.command.MbrRefundCommand;
import com.chuangjiangx.member.stored.ddd.application.dto.MbrRefundResult;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrAccount;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrAccountRepository;
import com.chuangjiangx.member.basic.ddd.domain.model.Member;
import com.chuangjiangx.member.basic.ddd.domain.model.MemberRepository;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrOrder;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrOrderRefund;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrOrderRepository;
import com.chuangjiangx.member.stored.ddd.domain.MbrRandomUtils;
import com.chuangjiangx.member.stored.ddd.domain.stardard.*;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreStream;
import com.chuangjiangx.member.score.ddd.domain.repository.MbrScoreStreamRepository;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrStoredStream;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrStoredStreamRepository;
import com.chuangjiangx.member.basic.ddd.domain.model.MerchantId;
import com.chuangjiangx.member.stored.ddd.domain.exception.MemberPaymentException;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrOrderRefundStatus;
import com.chuangjiangx.member.score.ddd.domain.model.MbrScoreType;
import com.chuangjiangx.member.stored.ddd.domain.model.MbrStoredType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * @author cj-ch
 * @date 2018/5/7 下午6:14
 */
@Service
public class MbrRefundApplication {

    @Autowired
    private MbrOrderRepository mbrOrderRepository;
    @Autowired
    private MbrAccountRepository mbrAccountRepository;
    @Autowired
    private MbrStoredStreamRepository mbrStoredStreamRepository;
    @Autowired
    private MbrScoreStreamRepository mbrScoreStreamRepository;
    @Autowired
    private MemberRepository memberRepository;

    @Transactional(rollbackFor = Exception.class)
    public MbrRefundResult refund(MbrRefundCommand command){
        MbrOrder mbrOrder = mbrOrderRepository.fromOrderNumber(command.getOrderNumber());
        if(mbrOrder == null){
            throw new MemberPaymentException("", "订单不存在");
        }
        if(!Objects.equals(mbrOrder.getPayEntry(),PayEntry.MSCARDPAY)){
            throw new MemberPaymentException("", "不支持非会员卡订单退款");
        }
        //退款操作校验
        mbrOrder.operateCheck(command.getMerchantId(),command.getStoreId(),command.getStoreUserId(),command.getUserType());
        MbrOrderRefund refund = new MbrOrderRefund(
                mbrOrder.getId(),
                MbrRandomUtils.generateMbrRefundOrderNumber(),
                new MerchantId(command.getMerchantId()),
                command.getMerchantUserId(),
                mbrOrder.getMemberId(),
                command.getStoreId(),
                command.getStoreUserId(),
                MbrOrderRefundStatus.PROCESSING,
                command.getAmount(),
                null,
                command.getTerminal()
        );
        Member member = memberRepository.fromId(mbrOrder.getMemberId());
        MbrAccount mbrAccount = mbrAccountRepository.fromMemberId(mbrOrder.getMemberId());

        MbrRefundContext context = new MbrRefundContext();
        context.setMbrOrder(mbrOrder);
        context.setMbrOrderRefund(refund);
        context.setMbrAccount(mbrAccount);
        context.setMember(member);
        MbrStoredStream storedStream = mbrStoredStreamRepository.from(mbrOrder.getId().getId(), MbrStoredType.CONSUMER);
        if(null != storedStream){
            MbrScoreStream mbrScoreStream = mbrScoreStreamRepository.fromMbrStoreStreamIdAndType(storedStream.getId().getId(), MbrScoreType.CONSUMER);
            context.setMbrScoreStreamHis(mbrScoreStream);
        }
        StandardMbrRefund mbrRefund = new StandardMbrRefund(context);
        MbrRefundDomainResult refundResult = mbrRefund.refund();
        MbrRefundResult result = new MbrRefundResult();
        BeanUtils.copyProperties(refundResult,result);
        return result;
    }
}
